package com.dsp.soundscape.controller;

import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;

import com.dsp.soundscape.model.AlbumInfo;
import com.dsp.soundscape.model.ZipInfo;
import com.dsp.soundscape.server.SoundscapeDataset;
import com.dsp.soundscape.server.SoundscapeLoader;
import com.dsp.soundscape.util.ZipUtil;

@Controller
public class SoundscapeController {
	private SoundscapeLoader loader;
	private ZipUtil zipper;
	
	@Autowired
	public void setLoader(SoundscapeLoader loader) {
		this.loader = loader;
	}

	@Autowired
	public void setZipper(ZipUtil zipper) {
		this.zipper = zipper;
	}

	@RequestMapping( method=RequestMethod.GET, value="index" )
	public String showHomePage(ModelMap map, WebRequest request, HttpServletResponse response) {

		SoundscapeDataset dataset = loader.getDataSet();
		String relativeContext = (String) request.getAttribute("relativeContext", WebRequest.SCOPE_REQUEST);
		if (relativeContext == null) {
			request.setAttribute("relativeContext", "../", WebRequest.SCOPE_REQUEST);
		}
		request.setAttribute("dataset", dataset, WebRequest.SCOPE_REQUEST);
		
		return "forward:/catalog/year/" + dataset.getLatestYear();
	}
 	
	@RequestMapping( method=RequestMethod.GET, value="year/{year}" )
	public String showYear(@PathVariable String year,
			ModelMap map, WebRequest request, HttpServletResponse response) {
		
		SoundscapeDataset dataset = yearDataset(request, map);
		List<AlbumInfo> info = dataset.getAlbumsByYear(year);
		
		if (info == null || info.isEmpty()) {
			response.setStatus(HttpServletResponse.SC_NOT_FOUND);
			return "forward:/404.html";
			
		} else {
			populateThumbnails(info);
			populateHeaderData(map, dataset, 2);
			map.addAttribute("currentView", info);
			map.addAttribute("selectedText", year);
			map.addAttribute("selectedLabel", "Year");
		}
		
		return "forward:/main.jsp";
	}
	
	@RequestMapping( method=RequestMethod.GET, value="artist/{artist}" )
	public String showArtist(@PathVariable String artist,
			ModelMap map, WebRequest request, HttpServletResponse response) {

		SoundscapeDataset dataset = loader.getDataSet();
		List<AlbumInfo> info = dataset.getAlbumsByArtist(artist);
		
		if (info == null || info.isEmpty()) {
			response.setStatus(HttpServletResponse.SC_NOT_FOUND);
			return "forward:/404.html";
			
		} else {
			populateThumbnails(info);
			populateHeaderData(map, dataset, 2);
			map.addAttribute("currentView", info);
			map.addAttribute("selectedText", info.get(0).getArtist());
			map.addAttribute("selectedLabel", "Artist");
		}
		
		return "forward:/main.jsp";
	}
	
	@RequestMapping( method=RequestMethod.GET, value="album/{artist}/{year}/{album}" )
	public String showAlbum(@PathVariable String artist, @PathVariable String year, @PathVariable String album, 
			ModelMap map, WebRequest request, HttpServletResponse response) {

		SoundscapeDataset dataset = loader.getDataSet();
		AlbumInfo info = dataset.getAlbumInfo(artist, year, album);
		
		if (info == null) {
			response.setStatus(HttpServletResponse.SC_NOT_FOUND);
			return "forward:/404.html";
			
		} else {
			loader.populate(info);
			
			map.addAttribute("album", info);
			map.addAttribute("selectedText", info.getAlbum());
			map.addAttribute("selectedLabel", "Album");
			
			ZipInfo zipped = zipper.ifZipped(info);
			if (zipped != null) {
				map.addAttribute("zipped", zipped);
			}
			populateHeaderData(map, dataset, 4);
		}
		
		return "forward:/album.jsp";
	}
	
	@ResponseBody
	@RequestMapping( method=RequestMethod.GET, value="zip/{artist}/{year}/{album}" )
	public ZipInfo zipAlbum(@PathVariable String artist, @PathVariable String year, @PathVariable String album, 
			ModelMap map, WebRequest request, HttpServletResponse response) {
		SoundscapeDataset dataset = loader.getDataSet();
		AlbumInfo info = dataset.getAlbumInfo(artist, year, album);
		loader.populate(info);
		return zipper.createZipFile(info);
	}
	
	@ResponseBody
	@RequestMapping( method=RequestMethod.GET, value="progress/{artist}/{year}/{album}" )
	public ZipInfo zipProgress(@PathVariable String artist, @PathVariable String year, @PathVariable String album) {
		return zipper.getProgress(artist + "/" + year + "/" + album);
	}
	
	private void populateThumbnails(List<AlbumInfo> info) {
		SoundscapeDataset dataset = loader.getDataSet();
		for (AlbumInfo album : info) {
			dataset.getAlbumInfo(album.getArtistRest(), album.getYear(), album.getAlbumRest());
			loader.thumbnails(album);
		}
	}
	
	private void populateHeaderData(ModelMap map, SoundscapeDataset dataset, int relativeDepth) {
		map.addAttribute("version", loader.getVersion().getFullVersion());
		map.addAttribute("albumCount", dataset.getAlbumCount());
		map.addAttribute("artistCount", dataset.getArtistCount());
		
		if (!map.containsKey("relativeContext")) {
			String relativeContext = "";
			for (int i = 0; i < relativeDepth; i++) {
				relativeContext += "../";
			}
			
			map.addAttribute("relativeContext", relativeContext);
		}
	}
	
	private SoundscapeDataset yearDataset(WebRequest request, ModelMap map) {
		SoundscapeDataset dataset = (SoundscapeDataset) request.getAttribute("dataset", WebRequest.SCOPE_REQUEST);
		String relativeContext = (String) request.getAttribute("relativeContext", WebRequest.SCOPE_REQUEST);
		if (relativeContext != null) {
			map.addAttribute("relativeContext", relativeContext);
		}
		return (dataset == null) ? loader.getDataSet() : dataset;
	}
	
}
